<?php
// +----------------------------------------------------------------------
// | 萤火商城系统 [ 致力于通过产品和服务，帮助商家高效化开拓市场 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2017~2024 https://www.yiovo.com All rights reserved.
// +----------------------------------------------------------------------
// | Licensed 这不是一个自由软件，不允许对程序代码以任何形式任何目的的再发行
// +----------------------------------------------------------------------
// | Author: 萤火科技 <admin@yiovo.com>
// +----------------------------------------------------------------------
declare (strict_types=1);

namespace cores\authorize\update;

use cores\library\Download;
use cores\library\backup\Files as FilesBackup;
use cores\exception\BaseException;

/**
 * 一键更新服务(后端文件)
 * Class Server
 */
class Server
{
    // 当前要升级的版本号
    private string $version;

    // 当前的模块信息
    private array $moduleInfo = [];

    // 升级包文件名称 (下载后)
    private string $fileName = 'server.zip';

    // 下载类的实例
    private static $downloadInstantiate;

    // 文件备份类的实例
    private static $filesBackupInstantiate;

    /**
     * 构造方法
     * @param string $version
     * @param array $moduleInfo
     */
    public function __construct(string $version, array $moduleInfo)
    {
        $this->version = $version;
        $this->moduleInfo = $moduleInfo;
    }

    /**
     * 执行一键更新服务端
     * @throws BaseException
     */
    public function handle()
    {
        if (!empty($this->moduleInfo['download_url'])) {
            // 1. 备份后端文件
            $this->backup();
            // 2. 下载升级包(后端文件)
            $this->download();
            // 3. 导入升级包(后端文件)
            $this->import();
        }
    }

    /**
     * 备份指定的文件
     * @return void
     * @throws BaseException
     */
    private function backup(): void
    {
        if (empty($this->moduleInfo['update_content'])) {
            return;
        }
        // 备份的文件列表
        $backupFileList = $this->moduleInfo['update_content'];
        $this->getFilesBackupInstantiate()->backup($backupFileList);
    }

    /**
     * 下载升级包
     * @return void
     * @throws BaseException
     */
    private function download(): void
    {
        $this->getDownloadInstantiate()->download();
        if (!file_exists($this->getDownloadInstantiate()->getFilePath())) {
            throwError('后端升级文件不存在');
        }
    }

    /**
     * 导入升级包(后端文件)
     * @throws BaseException
     */
    private function import()
    {
        $package = $this->getDownloadInstantiate()->getFilePath();
        if (!$this->getFilesBackupInstantiate()->import($package)) {
            throwError('后端升级文件导入失败');
        }
    }

    /**
     * 获取备份文件夹路径
     * @return string
     */
    private function getBackupPath(): string
    {
        return runtime_root_path() . "admin/backup/v{$this->version}/files/";
    }

    /**
     * 获取文件备份类的实例
     * @return FilesBackup
     * @throws BaseException
     */
    private function getFilesBackupInstantiate(): FilesBackup
    {
        if (!self::$filesBackupInstantiate) {
            self::$filesBackupInstantiate = new FilesBackup([
                'path' => $this->getBackupPath()
            ]);
        }
        return self::$filesBackupInstantiate;
    }

    /**
     * 获取下载类的实例
     * @return Download
     */
    private function getDownloadInstantiate(): Download
    {
        if (!self::$downloadInstantiate) {
            $folderPath = runtime_root_path() . "admin/update/v{$this->version}/";
            self::$downloadInstantiate = (new Download)->setFolderPath($folderPath)
                ->setFileName($this->fileName)
                ->setUrl($this->moduleInfo['download_url']);
        }
        return self::$downloadInstantiate;
    }
}